/*
 * Путь на клетчатом поле
 * vim:foldmethod=marker:
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#define N_MAX	1000

struct queue {
	struct dot	*data;
	long		head;
	long		size;
	long		size_max;
};

struct dot {
	short	x, y;
};

struct field {
	uint8_t	available;
	uint8_t	visited;
	short	dist;
	struct dot prev;
};


static const struct dot directions[4] = {
	{  1,  0 },
	{ -1,  0 },
	{  0,  1 },
	{  0, -1 }
};

int_fast8_t
sgn(int a)
{
	if (a > 0) return 1;
	if (a < 0) return -1;
	return 0;
}


/* {{{ queue and adjlist interface functions */
void
queue_init(struct queue *q, int size)
{
	q->data = (struct dot *) calloc(size, sizeof *q->data);
	q->head = 0;
	q->size = 0;
	q->size_max = size;
}

void
enqueue(struct queue *q, struct dot x)
{
	if (q->size >= q->size_max)
		fprintf(stderr, "queue overflow. failed to add x={ .x=%d, .y=%d }\n", x.x, x.y);
	else
		q->data[(q->head + q->size++) % q->size_max] = x;
}

struct dot
dequeue(struct queue *q)
{
	struct dot ret = q->data[q->head % q->size_max];
	if (!q->size)
		return ret; /* a.k.a. UB */
	--q->size;
	if (++q->head == q->size_max)
		q->head = 0;
	return ret;
}

uint8_t
queue_isempty(struct queue *q)
{
	return (q->size > 0) ? 0 : 1;
}
/* }}} */

/* {{{ an example implementation
int
bfs(struct adjlist *al, struct queue *q, const int index, const int final)
{
	int u = 0;
	Node *node = NULL;

	if (index == final) {
		(void) printf("0\n%d\n", final + 1);
		return 0;
	}

	al[index].visited = 1;
	al[index].prev	  = -1;
	al[index].dist	  = 0;
	enqueue(q, index);

	while (!queue_isempty(q)) {
		u = dequeue(q);
		node = al[u].first;
		while (node) {
			if (node->x == final) {
				al[node->x].dist = al[u].dist + 1;
				al[node->x].prev = u;
				print_path(al, final);
				return 0;
			}
			if (!al[node->x].visited) {
				al[node->x].visited = 1;
				al[node->x].dist = al[u].dist + 1;
				al[node->x].prev = u;
				enqueue(q, node->x);
			}
			node = node->next;
		}
	}
	return -1;
}
   }}} */

#ifdef DEBUG
void
print_fancy_map(const struct field **A)
{
	static const char null[] = " ·";
	static const char avail[] = " *";
	register short i = 0, j = 0;

	while (i < 40) {
		j = 0;
		while (j < 40) {
			A[i][j].available ?
				fputs(avail, stderr)
				: fputs(null, stderr);
			++j;
		}
		putc('\n', stderr);
		++i;
	}
}
#endif

void
add_segment(struct field **A, const struct dot a, const struct dot b)
{
	register short i;

	if (a.x == b.x) {
		for (i = a.y; i != b.y; i += sgn(b.y - a.y)) {
#ifdef DEBUG
			(void) fprintf(stderr, "A[a.x=%hd][i=%hd].available=%hhd ← 1\n",
					a.x, i, A[a.x][i].available);
#endif
			A[a.x][i].available = 1;
		}
#ifdef DEBUG
		(void) fprintf(stderr, "A[a.x=%hd][i=%hd].available=%hhd ← 1\n",
				a.x, i, A[a.x][i].available);
#endif
		A[a.x][i].available = 1;
	} else if (a.y == b.y) {
		for (i = a.x; i != b.x; i += sgn(b.x - a.x)) {
#ifdef DEBUG
			(void) fprintf(stderr, "A[i=%hd][a.y=%hd].available=%hhd ← 1\n",
					i, a.y, A[i][a.y].available);
#endif
			A[i][a.y].available = 1;
		}
#ifdef DEBUG
		(void) fprintf(stderr, "A[i=%hd][a.y=%hd].available=%hhd ← 1\n",
				i, a.y, A[i][a.y].available);
#endif
		A[i][a.y].available = 1;
	} else
		(void) fputs("wtf?\n", stderr);
}

#ifdef DEBUG
void
print_path(struct field **A, struct dot fin)
{
	static struct dot rev_path[1000];
	register short i = 0;

	do {
		rev_path[i++] = fin;
		fin = A[fin.x][fin.y].prev;
	} while (fin.x != -1 || fin.y != -1);
	rev_path[i++] = fin; //dafuq?

	while (--i >= 0) {
		(void) fprintf(stderr, " (%d,%d)\n",
				rev_path[i].x, rev_path[i].y);
	}
}
#endif

int
bfs(struct field **A, struct queue *q, const struct dot s, const struct dot f)
{
	struct dot u = s;
	register short i = 0;
	struct dot tmp = { 0, 0 };

	if (!A[u.x][u.y].available)
		(void) fputs("D: starting point is not on a path that's marked available\n"
			     "D: expecting \"-1\"\n", stderr);

	A[u.x][u.y].visited = 1;
	A[u.x][u.y].prev.x = A[u.x][u.y].prev.y = -1;
	A[u.x][u.y].dist = 0;
	enqueue(q, u);

	while (!queue_isempty(q)) {
		u = dequeue(q);
		for (i = 0; i < 4; i++) {
			tmp.x = u.x + directions[i].x;
			tmp.y = u.y + directions[i].y;
			if (tmp.x >= 0 && tmp.x < 40 && tmp.y >= 0 && tmp.y < 40 &&
			    !A[tmp.x][tmp.y].visited &&
			    A[tmp.x][tmp.y].available) {
				A[tmp.x][tmp.y].visited = 1;
				A[tmp.x][tmp.y].dist = A[u.x][u.y].dist + 1;
				A[tmp.x][tmp.y].prev = u;
				enqueue(q, tmp);
			}
			if (tmp.x == f.x && tmp.y == f.y) {
#ifdef DEBUG
				print_path(A, f);
#endif
				(void) printf("%d\n", A[tmp.x][tmp.y].dist / 2);
				return A[tmp.x][tmp.y].dist;
			}
		}
	}

	(void) puts("-1");
	return -1;
}

int
main(void)
{
	struct queue	q;
	int		n;
	struct dot	s, f;
	struct dot	a, b;
	struct field	**A = NULL;
	register int	i = 0;

	(void) scanf("%hd%hd%hd%hd%d",
		&s.x, &s.y, &f.x, &f.y,
		&n);
	s.x <<= 1, s.y <<= 1, f.x <<=1, f.y <<= 1;

	queue_init(&q, 200000);
	A = (struct field **) calloc(40, sizeof *A);
	for (i = 0; i < 40; i++)
		A[i] = (struct field *) calloc(40, sizeof **A);

	for (i = 0; i < n; i++) {
		(void) scanf("%hd%hd%hd%hd",
			&a.x, &a.y, &b.x, &b.y);
		a.x *= 2, a.y *= 2, b.x *= 2, b.y *= 2;
		add_segment(A, a, b);
#ifdef DEBUG
		print_fancy_map((const struct field **) A);
#endif
	}

	bfs(A, &q, s, f);

exit:
	free(q.data);
	for (i = 0; i < 40; i++)
		free(A[i]);
	free(A);
	return 0;
}
